<template>
  <el-scrollbar height="100vh">
    <div class="container">
      <el-affix :offset="1">
        <h1 class="title">矢量图 - 高亮模块</h1>
      </el-affix>
      <div id="map1" class="map-x" ref="mapBox"></div>
      <div class="popup" v-show="shopPopup" ref="popup">
        <span>adcode: {{ data.adcode}}</span>
        <span>name: {{ data.name}}</span>
        <span>level: {{ data.level}}</span>
      </div>
      <dl>
        <dt>ol.style属性及子类</dt>
        <dd>可以配置的项：</dd>
        <div class="codestyle"><Code1 /></div>
        <dd>子类：</dd>
        <div class="codestyle"><Code2 /></div>
      </dl>
      <dd>所有代码：</dd>
      <div class="codestyle"><Code /></div>
    </div>
  </el-scrollbar>
</template>
<script>
import { onMounted, reactive, ref, toRefs } from 'vue-demi'
import Code from './code.vue'
import Code1 from './code1.vue'
import Code2 from './code2.vue'
import 'ol/ol.css'
import { Map, Overlay, View } from 'ol'
import { Style, Fill, Stroke, Text } from 'ol/style'
import LayerVector from 'ol/layer/Vector'
import SourceVector from 'ol/source/Vector'
import QH from '@/geo/QH.json'
import GeoJSON from 'ol/format/GeoJSON'

export default {
  setup () {
    const state = reactive({
      map: null,
      mapBox: ref(null),
      popup: ref(null),
      overlay: null,
      shopPopup: false,
      highlightStyle: new Style({
        stroke: new Stroke({
          color: '#f00',
          width: 1
        }),
        fill: new Fill({
          color: 'rgba(255, 0, 0, 0.1)'
        }),
        text: new Text({
          font: '12px Calibri, sans-serif',
          fill: new Fill({
            color: '#000'
          }),
          stroke: new Stroke({
            color: '#f00',
            width: 3
          })
        })
      }),
      highlight: null,
      featureOverlay: null,
      data: {}
    })

    const init = () => {
      const displayFeatureInfo = (pixel, evt) => {
        if (!state.featureOverlay) {
          state.featureOverlay = new LayerVector({
            source: new SourceVector(),
            map: state.map,
            style: feature => {
              state.highlightStyle.getText().setText(feature.get('name'))
              return state.highlightStyle
            }
          })
        }

        const feature = state.map.forEachFeatureAtPixel(pixel, feature => feature)

        if (feature !== state.highlight) {
          if (state.highlight) {
            state.shopPopup = false
            state.data = {}
            state.featureOverlay.getSource().removeFeature(state.highlight)
          }
          if (feature) {
            // 鼠标放到图层时改变鼠标样式
            state.map.getTargetElement().style.cursor = state.map.hasFeatureAtPixel(evt.pixel) ? 'pointer' : ''
            state.data = feature.values_
            state.featureOverlay.getSource().addFeature(feature)
            state.shopPopup = true
            state.overlay.setPosition(evt.coordinate)
          }
          state.highlight = feature
        }
      }

      const style = new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.6)'
        }),
        stroke: new Stroke({
          color: '#319FD3',
          width: 1
        }),
        text: new Text({
          font: '12px Calibri,sans-serif',
          fill: new Fill({
            color: '#000'
          }),
          stroke: new Stroke({
            color: '#fff',
            width: 3
          })
        })
      })

      state.overlay = new Overlay({
        element: state.popup, // 弹窗标签，在html里
        stopEvent: false,
        positioning: 'top-right',
        offset: [40, 40]
      })

      const vectorLayer = new LayerVector({
        source: new SourceVector({
          features: new GeoJSON().readFeatures(QH, {
            dataProjection: 'EPSG:4326',
            featureProjection: 'EPSG:4326'
          })
        }),
        style: feature => {
          style.getText().setText(feature.get('name'))
          return style
        }
      })

      state.map = new Map({
        target: state.mapBox,
        layers: [vectorLayer],
        overlays: [state.overlay],
        view: new View({
          projection: 'EPSG:4326',
          center: [98.860775, 35.521945],
          zoom: 6
        })
      })

      state.map.on('pointermove', evt => {
        if (evt.dragging) {
          return
        }
        const pixel = state.map.getEventPixel(evt.originalEvent)
        displayFeatureInfo(pixel, evt)
      })

      // state.map.on('click', evt => {
      //   displayFeatureInfo(evt.pixel, evt)
      // })
    }

    onMounted(() => {
      init()
    })
    return {
      ...toRefs(state)
    }
  },
  components: {
    Code, Code1, Code2
  }
}
</script>
<style lang="scss" scoped>
@import '../../css/main.scss';
.popup {
  width: 200px;
  height: 50px;
  background: blue;
  position: absolute;
  top: -115px;
  left: -150px;
  box-sizing: border-box;
  border-radius: 10px;
  span {
    display: block;
    font-size: 14px;
    color: #fff;
  }
  &::after {
    content: '';
    display: block;
    position: absolute;
    width: 20px;
    height: 20px;
    background: blue;
    bottom: -6px;
    left: 50%;
    z-index: -1;
    transform: translateX(-50%) rotate(45deg);
  }
}
</style>
